<!DOCTYPE html>
<html>
<head>
<title>README</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style type="text/css">
/* GitHub stylesheet for MarkdownPad (http://markdownpad.com) */
/* Author: Nicolas Hery - http://nicolashery.com */
/* Version: b13fe65ca28d2e568c6ed5d7f06581183df8f2ff */
/* Source: https://github.com/nicolahery/markdownpad-github */

/* RESET
=============================================================================*/

html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video {
  margin: 0;
  padding: 0;
  border: 0;
}

/* BODY
=============================================================================*/

body {
  font-family: Helvetica, arial, freesans, clean, sans-serif;
  font-size: 14px;
  line-height: 1.6;
  color: #333;
  background-color: #fff;
  padding: 20px;
  max-width: 960px;
  margin: 0 auto;
}

body>*:first-child {
  margin-top: 0 !important;
}

body>*:last-child {
  margin-bottom: 0 !important;
}

/* BLOCKS
=============================================================================*/

p, blockquote, ul, ol, dl, table, pre {
  margin: 15px 0;
}

/* HEADERS
=============================================================================*/

h1, h2, h3, h4, h5, h6 {
  margin: 20px 0 10px;
  padding: 0;
  font-weight: bold;
  -webkit-font-smoothing: antialiased;
}

h1 tt, h1 code, h2 tt, h2 code, h3 tt, h3 code, h4 tt, h4 code, h5 tt, h5 code, h6 tt, h6 code {
  font-size: inherit;
}

h1 {
  font-size: 28px;
  color: #000;
}

h2 {
  font-size: 24px;
  border-bottom: 1px solid #ccc;
  color: #000;
}

h3 {
  font-size: 18px;
}

h4 {
  font-size: 16px;
}

h5 {
  font-size: 14px;
}

h6 {
  color: #777;
  font-size: 14px;
}

body>h2:first-child, body>h1:first-child, body>h1:first-child+h2, body>h3:first-child, body>h4:first-child, body>h5:first-child, body>h6:first-child {
  margin-top: 0;
  padding-top: 0;
}

a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
  margin-top: 0;
  padding-top: 0;
}

h1+p, h2+p, h3+p, h4+p, h5+p, h6+p {
  margin-top: 10px;
}

/* LINKS
=============================================================================*/

a {
  color: #4183C4;
  text-decoration: none;
}

a:hover {
  text-decoration: underline;
}

/* LISTS
=============================================================================*/

ul, ol {
  padding-left: 30px;
}

ul li > :first-child, 
ol li > :first-child, 
ul li ul:first-of-type, 
ol li ol:first-of-type, 
ul li ol:first-of-type, 
ol li ul:first-of-type {
  margin-top: 0px;
}

ul ul, ul ol, ol ol, ol ul {
  margin-bottom: 0;
}

dl {
  padding: 0;
}

dl dt {
  font-size: 14px;
  font-weight: bold;
  font-style: italic;
  padding: 0;
  margin: 15px 0 5px;
}

dl dt:first-child {
  padding: 0;
}

dl dt>:first-child {
  margin-top: 0px;
}

dl dt>:last-child {
  margin-bottom: 0px;
}

dl dd {
  margin: 0 0 15px;
  padding: 0 15px;
}

dl dd>:first-child {
  margin-top: 0px;
}

dl dd>:last-child {
  margin-bottom: 0px;
}

/* CODE
=============================================================================*/

pre, code, tt {
  font-size: 12px;
  font-family: Consolas, "Liberation Mono", Courier, monospace;
}

code, tt {
  margin: 0 0px;
  padding: 0px 0px;
  white-space: nowrap;
  border: 1px solid #eaeaea;
  background-color: #f8f8f8;
  border-radius: 3px;
}

pre>code {
  margin: 0;
  padding: 0;
  white-space: pre;
  border: none;
  background: transparent;
}

pre {
  background-color: #f8f8f8;
  border: 1px solid #ccc;
  font-size: 13px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 10px;
  border-radius: 3px;
}

pre code, pre tt {
  background-color: transparent;
  border: none;
}

kbd {
    -moz-border-bottom-colors: none;
    -moz-border-left-colors: none;
    -moz-border-right-colors: none;
    -moz-border-top-colors: none;
    background-color: #DDDDDD;
    background-image: linear-gradient(#F1F1F1, #DDDDDD);
    background-repeat: repeat-x;
    border-color: #DDDDDD #CCCCCC #CCCCCC #DDDDDD;
    border-image: none;
    border-radius: 2px 2px 2px 2px;
    border-style: solid;
    border-width: 1px;
    font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;
    line-height: 10px;
    padding: 1px 4px;
}

/* QUOTES
=============================================================================*/

blockquote {
  border-left: 4px solid #DDD;
  padding: 0 15px;
  color: #777;
}

blockquote>:first-child {
  margin-top: 0px;
}

blockquote>:last-child {
  margin-bottom: 0px;
}

/* HORIZONTAL RULES
=============================================================================*/

hr {
  clear: both;
  margin: 15px 0;
  height: 0px;
  overflow: hidden;
  border: none;
  background: transparent;
  border-bottom: 4px solid #ddd;
  padding: 0;
}

/* TABLES
=============================================================================*/

table th {
  font-weight: bold;
}

table th, table td {
  border: 1px solid #ccc;
  padding: 6px 13px;
}

table tr {
  border-top: 1px solid #ccc;
  background-color: #fff;
}

table tr:nth-child(2n) {
  background-color: #f8f8f8;
}

/* IMAGES
=============================================================================*/

img {
  max-width: 100%
}
</style>
<style type="text/css">
.highlight  { background: #ffffff; }
.highlight .c { color: #999988; font-style: italic } /* Comment */
.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */
.highlight .k { font-weight: bold } /* Keyword */
.highlight .o { font-weight: bold } /* Operator */
.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */
.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */
.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */
.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */
.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */
.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */
.highlight .ge { font-style: italic } /* Generic.Emph */
.highlight .gr { color: #aa0000 } /* Generic.Error */
.highlight .gh { color: #999999 } /* Generic.Heading */
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
.highlight .go { color: #888888 } /* Generic.Output */
.highlight .gp { color: #555555 } /* Generic.Prompt */
.highlight .gs { font-weight: bold } /* Generic.Strong */
.highlight .gu { color: #aaaaaa } /* Generic.Subheading */
.highlight .gt { color: #aa0000 } /* Generic.Traceback */
.highlight .kc { font-weight: bold } /* Keyword.Constant */
.highlight .kd { font-weight: bold } /* Keyword.Declaration */
.highlight .kp { font-weight: bold } /* Keyword.Pseudo */
.highlight .kr { font-weight: bold } /* Keyword.Reserved */
.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */
.highlight .m { color: #009999 } /* Literal.Number */
.highlight .s { color: #d14 } /* Literal.String */
.highlight .na { color: #008080 } /* Name.Attribute */
.highlight .nb { color: #0086B3 } /* Name.Builtin */
.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */
.highlight .no { color: #008080 } /* Name.Constant */
.highlight .ni { color: #800080 } /* Name.Entity */
.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */
.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */
.highlight .nn { color: #555555 } /* Name.Namespace */
.highlight .nt { color: #000080 } /* Name.Tag */
.highlight .nv { color: #008080 } /* Name.Variable */
.highlight .ow { font-weight: bold } /* Operator.Word */
.highlight .w { color: #bbbbbb } /* Text.Whitespace */
.highlight .mf { color: #009999 } /* Literal.Number.Float */
.highlight .mh { color: #009999 } /* Literal.Number.Hex */
.highlight .mi { color: #009999 } /* Literal.Number.Integer */
.highlight .mo { color: #009999 } /* Literal.Number.Oct */
.highlight .sb { color: #d14 } /* Literal.String.Backtick */
.highlight .sc { color: #d14 } /* Literal.String.Char */
.highlight .sd { color: #d14 } /* Literal.String.Doc */
.highlight .s2 { color: #d14 } /* Literal.String.Double */
.highlight .se { color: #d14 } /* Literal.String.Escape */
.highlight .sh { color: #d14 } /* Literal.String.Heredoc */
.highlight .si { color: #d14 } /* Literal.String.Interpol */
.highlight .sx { color: #d14 } /* Literal.String.Other */
.highlight .sr { color: #009926 } /* Literal.String.Regex */
.highlight .s1 { color: #d14 } /* Literal.String.Single */
.highlight .ss { color: #990073 } /* Literal.String.Symbol */
.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */
.highlight .vc { color: #008080 } /* Name.Variable.Class */
.highlight .vg { color: #008080 } /* Name.Variable.Global */
.highlight .vi { color: #008080 } /* Name.Variable.Instance */
.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */
.pl-c {
    color: #969896;
}

.pl-c1,.pl-mdh,.pl-mm,.pl-mp,.pl-mr,.pl-s1 .pl-v,.pl-s3,.pl-sc,.pl-sv {
    color: #0086b3;
}

.pl-e,.pl-en {
    color: #795da3;
}

.pl-s1 .pl-s2,.pl-smi,.pl-smp,.pl-stj,.pl-vo,.pl-vpf {
    color: #333;
}

.pl-ent {
    color: #63a35c;
}

.pl-k,.pl-s,.pl-st {
    color: #a71d5d;
}

.pl-pds,.pl-s1,.pl-s1 .pl-pse .pl-s2,.pl-sr,.pl-sr .pl-cce,.pl-sr .pl-sra,.pl-sr .pl-sre,.pl-src,.pl-v {
    color: #df5000;
}

.pl-id {
    color: #b52a1d;
}

.pl-ii {
    background-color: #b52a1d;
    color: #f8f8f8;
}

.pl-sr .pl-cce {
    color: #63a35c;
    font-weight: bold;
}

.pl-ml {
    color: #693a17;
}

.pl-mh,.pl-mh .pl-en,.pl-ms {
    color: #1d3e81;
    font-weight: bold;
}

.pl-mq {
    color: #008080;
}

.pl-mi {
    color: #333;
    font-style: italic;
}

.pl-mb {
    color: #333;
    font-weight: bold;
}

.pl-md,.pl-mdhf {
    background-color: #ffecec;
    color: #bd2c00;
}

.pl-mdht,.pl-mi1 {
    background-color: #eaffea;
    color: #55a532;
}

.pl-mdr {
    color: #795da3;
    font-weight: bold;
}

.pl-mo {
    color: #1d3e81;
}
.task-list {
padding-left:10px;
margin-bottom:0;
}

.task-list li {
    margin-left: 20px;
}

.task-list-item {
list-style-type:none;
padding-left:10px;
}

.task-list-item label {
font-weight:400;
}

.task-list-item.enabled label {
cursor:pointer;
}

.task-list-item+.task-list-item {
margin-top:3px;
}

.task-list-item-checkbox {
display:inline-block;
margin-left:-20px;
margin-right:3px;
vertical-align:1px;
}
</style>
</head>
<body>
<h2>Jplus-core说明</h2>
<h3>声明</h3>
<p>jplus 是一个java框架，web只是他的一个模块，他并非重复造轮子，初衷是希望把所有好的合适的框架集合到一起，能发挥出对开发者更大的作用。<br>
框架思想主要学习黄勇 的smart，推荐大家去看看；</p>
<h3>关于Jplus</h3>
<ol>
<li>支持零配置，所有配置可由.properties或代码管理。</li>
<li>提供可以媲美Spring的 IOC、AOP、MVC，及各种强大的第三方定制插件。</li>
<li>快速开发，框架~200Kb,所有插件可插拔。</li>
</ol>
<h3>jplus 简介</h3>
<p><a href="https://camo.githubusercontent.com/fa504c9b1fde10af1c595ae701b0fda9d4ef93ed/687474703a2f2f7374617469632e6f736368696e612e6e65742f75706c6f6164732f73706163652f323031362f303832392f3039333430385f7177376e5f3232343139352e706e67" target="_blank"><img src="https://camo.githubusercontent.com/fa504c9b1fde10af1c595ae701b0fda9d4ef93ed/687474703a2f2f7374617469632e6f736368696e612e6e65742f75706c6f6164732f73706163652f323031362f303832392f3039333430385f7177376e5f3232343139352e706e67" alt="" data-canonical-src="http://static.oschina.net/uploads/space/2016/0829/093408_qw7n_224195.png" style="max-width:100%;"></a></p>
<blockquote>
<p><strong>项目启动顺序：</strong><br>
初始化 --&gt;CoreLoader --&gt;BeanHandle --&gt;ActionHandle --&gt;PluginHandle --&gt;AopHandle --&gt;IocHandle --&gt;完成</p>
<p><strong>关于Bean管理</strong><br>
项目启动后CoreLoader 加载 BeanHandle,同时BeanHandle 初始化ConfigHandle， 获取一系列相应的用户配置信息properties。<br>
然后扫描 ${app.scan.pkg} 包中所有带<a href="https://github.com/Component" class="user-mention">@Component</a>注解的class,完成bean的发现。<br>
<em>PS:在项目中运行时获取 bean 对象可以使用：BeanHandle.getBean(Classcls);</em></p>
</blockquote>
<hr>
<h3>1. 快速创建一个jplusMvc项目</h3>
<ol>
<li>
<p>首先我们创建一个simple Maven Project<br>
然后第一步创建一个<strong>HelloAction.java</strong>用于接收用户请求：</p>
<div class="highlight highlight-source-java"><pre><span class="pl-k">package</span> <span class="pl-smi">com.demo.mvc.action</span>;
<span class="pl-k">import</span> <span class="pl-smi">com.jplus.core.mvc.WebUtil</span>;
<span class="pl-k">import</span> <span class="pl-smi">com.jplus.core.mvc.annotation.Controller</span>;
<span class="pl-k">import</span> <span class="pl-smi">com.jplus.core.mvc.annotation.Request</span>;

<span class="pl-k">@Controller</span>
<span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-en">HelloAction</span> {

 	<span class="pl-k">@Request.All</span>(<span class="pl-s"><span class="pl-pds">"</span>{msg}<span class="pl-pds">"</span></span>)
 	<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">index</span>(<span class="pl-smi">String</span> <span class="pl-v">msg</span>) {
 		<span class="pl-smi">System</span><span class="pl-k">.</span>err<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>== This is Restful Action ===========<span class="pl-pds">"</span></span>);
 		<span class="pl-smi">WebUtil</span><span class="pl-k">.</span>writeHTML(msg);
 	}
}</pre></div>
</li>
<li>
<p>然后我们看见，包名是com.demo开始的，现在配置注解扫描配置，在project的classpath目录下，添加文件：<strong>app.properties</strong></p>
<div class="highlight highlight-source-java"><pre> app<span class="pl-k">.</span>scan<span class="pl-k">.</span>pkg<span class="pl-k">=</span>com<span class="pl-k">.</span>demo</pre></div>
</li>
<li>
<p>[附加]其实到第二步，项目就可以启动了，但为了debug方便，添加日志配置,在classpath目录下，添加：<strong>log4j.xml</strong></p>
<div class="highlight highlight-text-xml"><pre>&lt;?<span class="pl-ent">xml</span><span class="pl-e"> version</span>=<span class="pl-s"><span class="pl-pds">"</span>1.0<span class="pl-pds">"</span></span><span class="pl-e"> encoding</span>=<span class="pl-s"><span class="pl-pds">"</span>UTF-8<span class="pl-pds">"</span></span>?&gt;  
&lt;!<span class="pl-k">DOCTYPE</span> <span class="pl-c1">log4j:configuration</span> SYSTEM "log4j.dtd"&gt;
&lt;<span class="pl-ent">log4j</span><span class="pl-ent">:</span><span class="pl-ent">configuration</span> <span class="pl-e">xmlns</span><span class="pl-e">:</span><span class="pl-e">log4j</span>=<span class="pl-s"><span class="pl-pds">"</span>http://jakarta.apache.org/log4j/<span class="pl-pds">"</span></span> <span class="pl-e">debug</span>=<span class="pl-s"><span class="pl-pds">"</span>false<span class="pl-pds">"</span></span>&gt;
  <span class="pl-c"><span class="pl-c">&lt;!--</span> 控制台日志，开发阶段使用 <span class="pl-c">--&gt;</span></span>
  &lt;<span class="pl-ent">appender</span> <span class="pl-e">name</span>=<span class="pl-s"><span class="pl-pds">"</span>log_console<span class="pl-pds">"</span></span> <span class="pl-e">class</span>=<span class="pl-s"><span class="pl-pds">"</span>org.apache.log4j.ConsoleAppender<span class="pl-pds">"</span></span>&gt;
    &lt;<span class="pl-ent">param</span> <span class="pl-e">name</span>=<span class="pl-s"><span class="pl-pds">"</span>Threshold<span class="pl-pds">"</span></span> <span class="pl-e">value</span>=<span class="pl-s"><span class="pl-pds">"</span>info<span class="pl-pds">"</span></span> /&gt;
    &lt;<span class="pl-ent">layout</span> <span class="pl-e">class</span>=<span class="pl-s"><span class="pl-pds">"</span>org.apache.log4j.PatternLayout<span class="pl-pds">"</span></span>&gt;
      &lt;<span class="pl-ent">param</span> <span class="pl-e">name</span>=<span class="pl-s"><span class="pl-pds">"</span>ConversionPattern<span class="pl-pds">"</span></span> <span class="pl-e">value</span>=<span class="pl-s"><span class="pl-pds">"</span>%d %-5p %-30.30l -%m%n<span class="pl-pds">"</span></span> /&gt;
    &lt;/<span class="pl-ent">layout</span>&gt;
  &lt;/<span class="pl-ent">appender</span>&gt;
  &lt;<span class="pl-ent">root</span>&gt;
    &lt;<span class="pl-ent">appender-ref</span> <span class="pl-e">ref</span>=<span class="pl-s"><span class="pl-pds">"</span>log_console<span class="pl-pds">"</span></span> /&gt;
  &lt;/<span class="pl-ent">root</span>&gt;
&lt;/<span class="pl-ent">log4j</span><span class="pl-ent">:</span><span class="pl-ent">configuration</span>&gt;</pre></div>
</li>
<li>
<p>最后添加Tomcat容器，启动访问：<a href="http://localhost:8080/hello">localhost:8080/hello</a>试试吧~</p>
</li>
</ol>
<h3>2. 关于JplusMvc的相关配置</h3>
<ol>
<li>
<p>关于MVC注解</p>
<ul>
<li>
<p>注解：<strong><a href="https://github.com/Controller" class="user-mention">@Controller</a></strong><br>
使用说明：用于定义Action配置。类上加上此注解，该类将被定义为Action处理的接收类。<br>
使用方式：直接在请求处理类上加上此注解即可。</p>
</li>
<li>
<p>注解：<strong><a href="https://github.com/Request" class="user-mention">@Request</a></strong><br>
使用说明：用于定义请求的UrlMapping,对用户的请求根据路径做路由分发。<br>
使用方式：见下方代码，默认提供六种配置方式，对应于不同的http请求:<br>
<a href="https://github.com/Request" class="user-mention">@Request</a>("xxx")	=&gt; 用于公共请求前缀,作用于类上<br>
@Request.All("xxx")=&gt; 用于接受所有匹配的请求，作用于方法上<br>
@Request.Get("xxx")=&gt; 用于接受Http get请求，作用于方法上<br>
@Request.Post("xxx")=&gt; 用于接受Http post请求，作用于方法上<br>
@Request.Put("xxx")=&gt; 用于接受Http put请求，作用于方法上<br>
@Request.Delete("xxx")=&gt; 用于接受Http delete请求，作用于方法上</p>
<div class="highlight highlight-source-java"><pre><span class="pl-k">package</span> <span class="pl-smi">com.demo.mvc.action</span>;
<span class="pl-k">import</span> <span class="pl-smi">com.jplus.core.mvc.WebUtil</span>;
<span class="pl-k">import</span> <span class="pl-smi">com.jplus.core.mvc.annotation.Controller</span>;
<span class="pl-k">import</span> <span class="pl-smi">com.jplus.core.mvc.annotation.Request</span>;
<span class="pl-k">@Controller</span>
<span class="pl-k">@Request</span>(<span class="pl-s"><span class="pl-pds">"</span>user/<span class="pl-pds">"</span></span>)
<span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-en">UserAction</span> {

  <span class="pl-k">@Request.All</span>(<span class="pl-s"><span class="pl-pds">"</span>info<span class="pl-pds">"</span></span>)
    <span class="pl-k">private</span> <span class="pl-k">void</span> <span class="pl-en">info</span>() {
    <span class="pl-smi">WebUtil</span><span class="pl-k">.</span>writeHTML(<span class="pl-s"><span class="pl-pds">"</span>This is Page info<span class="pl-pds">"</span></span>);
  }

  <span class="pl-k">@Request.Get</span>(<span class="pl-s"><span class="pl-pds">"</span>{id}<span class="pl-pds">"</span></span>)
    <span class="pl-k">private</span> <span class="pl-k">void</span> <span class="pl-en">getUser</span>(<span class="pl-k">int</span> <span class="pl-v">id</span>) {
    <span class="pl-smi">WebUtil</span><span class="pl-k">.</span>writeHTML(<span class="pl-s"><span class="pl-pds">"</span>This is a get user info by id,id:<span class="pl-pds">"</span></span><span class="pl-k">+</span>id);
  }

  <span class="pl-k">@Request.Post</span>(<span class="pl-s"><span class="pl-pds">"</span>add<span class="pl-pds">"</span></span>)
    <span class="pl-k">private</span> <span class="pl-k">void</span> <span class="pl-en">addUser</span>() {
    <span class="pl-smi">WebUtil</span><span class="pl-k">.</span>writeHTML(<span class="pl-s"><span class="pl-pds">"</span>This is add Page<span class="pl-pds">"</span></span>);
  }

  <span class="pl-k">@Request.Put</span>(<span class="pl-s"><span class="pl-pds">"</span>edit<span class="pl-pds">"</span></span>)
    <span class="pl-k">private</span> <span class="pl-k">void</span> <span class="pl-en">editUser</span>() {
    <span class="pl-smi">WebUtil</span><span class="pl-k">.</span>writeHTML(<span class="pl-s"><span class="pl-pds">"</span>This is edit Page<span class="pl-pds">"</span></span>);
  }

  <span class="pl-k">@Request.Delete</span>(<span class="pl-s"><span class="pl-pds">"</span>{id}<span class="pl-pds">"</span></span>)
    <span class="pl-k">private</span> <span class="pl-k">void</span> <span class="pl-en">delUser</span>(<span class="pl-k">int</span> <span class="pl-v">id</span>) {
    <span class="pl-smi">WebUtil</span><span class="pl-k">.</span>writeHTML(<span class="pl-s"><span class="pl-pds">"</span>This is del Page,user id is :<span class="pl-pds">"</span></span> <span class="pl-k">+</span> id);
  }
}</pre></div>
</li>
<li>
<p>注解：<strong><a href="https://github.com/Param" class="user-mention">@Param</a></strong><br>
使用说明：用于设置请求入参，通过入参名称，获取restful/get/post形式的参数。<br>
使用方式：见下方代码：</p>
<div class="highlight highlight-source-java"><pre><span class="pl-c"><span class="pl-c">/*</span>*</span>
<span class="pl-c">* 发现和上面getUser的方法的区别了么，</span>
<span class="pl-c">* 上面直接取值，使用的下标取值，取的restful请求中的占位符{xx}中的值，然后按下标依次取，支持类型：int/long/Double/BigDecimal/String</span>
<span class="pl-c">* 下面通过@Param取值，使用名称key取值，可以取restful/get/post...等各种方式提交的值，支持类型：int/long/Double/BigDecimal/String</span>
<span class="pl-c"><span class="pl-c">*/</span></span>
<span class="pl-k">@Request.Get</span>(<span class="pl-s"><span class="pl-pds">"</span>{id}<span class="pl-pds">"</span></span>)
<span class="pl-k">private</span> <span class="pl-k">void</span> getUser2(<span class="pl-k">@Param</span>(<span class="pl-s"><span class="pl-pds">"</span>id<span class="pl-pds">"</span></span>) <span class="pl-k">int</span> userId) {
	<span class="pl-smi">WebUtil</span><span class="pl-k">.</span>writeHTML(<span class="pl-s"><span class="pl-pds">"</span>This is a get user info by id,id:<span class="pl-pds">"</span></span><span class="pl-k">+</span>userId);
}</pre></div>
</li>
<li>
<p>注解：<strong><a href="https://github.com/Form" class="user-mention">@Form</a></strong><br>
使用说明：用于标示POJO实体对象的请求入参，作用于实体类上。<br>
使用方式：当一个pojo实体对象为入参时（form表单提交），框架会自动将入参填充到对象中去。见下方代码：</p>
<div class="highlight highlight-source-java"><pre><span class="pl-k">==&gt;</span><span class="pl-smi">UserForm</span><span class="pl-k">.</span>java
<span class="pl-k">@Form</span>
<span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-en">User</span> {
  <span class="pl-k">private</span> <span class="pl-k">int</span> id;
  <span class="pl-k">private</span> <span class="pl-smi">String</span> name;
  <span class="pl-k">private</span> <span class="pl-smi">String</span> age;
  <span class="pl-c"><span class="pl-c">/*</span>* ... omit get/set/toString method ... <span class="pl-c">*/</span></span>
}
<span class="pl-k">--------------------------------------------------------------</span>
<span class="pl-k">==&gt;</span> <span class="pl-smi">UserAction</span><span class="pl-k">.</span>java
<span class="pl-k">@Request.Post</span>(<span class="pl-s"><span class="pl-pds">"</span>add<span class="pl-pds">"</span></span>)
<span class="pl-k">private</span> <span class="pl-k">void</span> addUser(<span class="pl-smi">User</span> user) {
  <span class="pl-smi">System</span><span class="pl-k">.</span>err<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>I can get form param:<span class="pl-pds">"</span></span><span class="pl-k">+</span> user<span class="pl-k">.</span>toString());
  <span class="pl-smi">WebUtil</span><span class="pl-k">.</span>writeHTML(<span class="pl-s"><span class="pl-pds">"</span>This is add Page<span class="pl-pds">"</span></span>);
}</pre></div>
</li>
<li>
<p>注解：<strong><a href="https://github.com/Service" class="user-mention">@Service</a></strong><br>
使用说明：用于标记实现类，供框架扫描，作为IOC注入到其他类中，作用于类上，一般用于Service层。又一个默认参数[名称]，非必填。<br>
使用方式：<a href="https://github.com/Service" class="user-mention">@Service</a>用于标记扫描，等待其他类使用<a href="https://github.com/Autowired" class="user-mention">@Autowired</a> 注入，<br>
<a href="https://github.com/Service" class="user-mention">@Service</a>可以添加参数名 <a href="https://github.com/Service" class="user-mention">@Service</a>("xxx"),然后注入的地方使用<a href="https://github.com/Autowired" class="user-mention">@Autowired</a>("xxx")进行注入，见下方代码：</p>
<div class="highlight highlight-source-java"><pre><span class="pl-k">==&gt;</span> <span class="pl-smi">UserService</span><span class="pl-k">.</span>java
<span class="pl-k">@Service</span>
<span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-en">UserService</span> {

<span class="pl-k">public</span> <span class="pl-smi">Result</span> <span class="pl-en">add</span>(<span class="pl-smi">User</span> <span class="pl-v">form</span>) {
  <span class="pl-smi">Result</span> res <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">Result</span>()<span class="pl-c1"><span class="pl-k">.</span>OK</span>();
  <span class="pl-smi">System</span><span class="pl-k">.</span>err<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>Add Service :<span class="pl-pds">"</span></span> <span class="pl-k">+</span> form<span class="pl-k">.</span>toString());
  <span class="pl-k">return</span> res;
  }
}

<span class="pl-k">--------------------------------------------------------------</span>
<span class="pl-k">==&gt;</span> <span class="pl-smi">UserAction</span><span class="pl-k">.</span>java

<span class="pl-k">@Controller</span>
<span class="pl-k">@Request</span>(<span class="pl-s"><span class="pl-pds">"</span>user/<span class="pl-pds">"</span></span>)
<span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-en">UserAction</span> {
<span class="pl-k">private</span> <span class="pl-k">@Autowired</span> <span class="pl-smi">UserService</span> userService;

<span class="pl-k">@Request.Post</span>(<span class="pl-s"><span class="pl-pds">"</span>add<span class="pl-pds">"</span></span>)
<span class="pl-k">private</span> <span class="pl-smi">Result</span> <span class="pl-en">addUser</span>(<span class="pl-smi">User</span> <span class="pl-v">form</span>) {
  <span class="pl-k">return</span> userService<span class="pl-k">.</span>add(form);
  }
}</pre></div>
</li>
</ul>
</li>
<li>
<p>关于MVC上下文</p>
<ul>
<li>
<p><strong>DataContext.java</strong><br>
DataContext为整个MVC的上下文容器，生产周期为当前请求。<br>
里面封装了<strong>Cookie,HttpServletRequest,HttpServletResponse,ServletContext,Session</strong>等相关对象的处理。</p>
</li>
<li>
<p><strong>WebUtil.java</strong><br>
Web 操作工具类,依赖于DataContext，提供了取参，输出，转发请求等实用功能。</p>
</li>
<li>
<p><strong>视图输出：View.java</strong><br>
视图输出，将请求执行完毕，返回到JSP页面进行渲染，然后返回也客户端页面。<br>
默认视图地址[在properties中配置]：<em>app.view.path=/WEB-INF/jsp/</em></p>
<div class="highlight highlight-source-java"><pre><span class="pl-k">@Controller</span>
<span class="pl-k">@Request</span>(<span class="pl-s"><span class="pl-pds">"</span>hello/<span class="pl-pds">"</span></span>)
<span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-en">HelloAction</span> {
  <span class="pl-k">@Request.All</span>(<span class="pl-s"><span class="pl-pds">"</span>page<span class="pl-pds">"</span></span>)
  <span class="pl-k">public</span> <span class="pl-smi">View</span> <span class="pl-en">page</span>() {
    <span class="pl-smi">System</span><span class="pl-k">.</span>err<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>== This is page Action ===========<span class="pl-pds">"</span></span>);
    <span class="pl-c"><span class="pl-c">//</span>跳转到 : /WEB-INF/jsp/hello/page.jsp</span>
    <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-smi">View</span>();
  }
}</pre></div>
</li>
<li>
<p><strong>JSON输出：Result.java</strong><br>
JSON输出，将请求执行完毕，返回到前端JSON字符串。<br>
推荐使用Result作为方法返回值。用户也可以<strong>自定义任何对象</strong>输出，默认都为JSON格式。</p>
<div class="highlight highlight-source-java"><pre><span class="pl-k">@Request.Get</span>(<span class="pl-s"><span class="pl-pds">"</span>JSON<span class="pl-pds">"</span></span>)
<span class="pl-k">public</span> <span class="pl-smi">Result</span> getJSON() {
  <span class="pl-smi">System</span><span class="pl-k">.</span>err<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>== This is page Action ===========<span class="pl-pds">"</span></span>);
  <span class="pl-c"><span class="pl-c">//</span> 返回JSON : {"code":1,"obj":"请求成功"}</span>
  <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-smi">Result</span>()<span class="pl-c1"><span class="pl-k">.</span>OK</span>()<span class="pl-c1"><span class="pl-k">.</span>DATA</span>(<span class="pl-s"><span class="pl-pds">"</span>请求成功<span class="pl-pds">"</span></span>);
}</pre></div>
</li>
</ul>
</li>
</ol>
<h3>3. 关于JplusAop的相关配置</h3>
<blockquote>
<p>说明：使用jdk，Cglib动态代理技术实现，采用责任链模式，递归代理。<br>
默认AOP提供三种代理：</p>
</blockquote>
<ol>
<li>
<p><strong>AspectProxy.java</strong> 切面代理，提供6种切点方法：</p>
<div class="highlight highlight-source-java"><pre><span class="pl-c"><span class="pl-c">//</span>开始</span>
<span class="pl-k">public</span> <span class="pl-k">void</span> begin() 
<span class="pl-c"><span class="pl-c">//</span>拦截[根据boolean判断是否继续执行方法]</span>
<span class="pl-k">public</span> <span class="pl-k">boolean</span> intercept(<span class="pl-k">Class&lt;?&gt;</span> cls, <span class="pl-smi">Method</span> method, <span class="pl-k">Object</span>[] params)  
<span class="pl-c"><span class="pl-c">//</span>方法执行前</span>
<span class="pl-k">public</span> <span class="pl-k">void</span> before(<span class="pl-k">Class&lt;?&gt;</span> cls, <span class="pl-smi">Method</span> method, <span class="pl-k">Object</span>[] params) throws <span class="pl-smi">Throwable</span> 
<span class="pl-c"><span class="pl-c">//</span>方法执行后</span>
<span class="pl-k">public</span> <span class="pl-k">void</span> after(<span class="pl-k">Class&lt;?&gt;</span> cls, <span class="pl-smi">Method</span> method, <span class="pl-k">Object</span>[] params, <span class="pl-smi">Object</span> result)  
<span class="pl-c"><span class="pl-c">//</span>抛出异常</span>
<span class="pl-k">public</span> <span class="pl-k">void</span> error(<span class="pl-k">Class&lt;?&gt;</span> cls, <span class="pl-smi">Method</span> method, <span class="pl-k">Object</span>[] params, <span class="pl-smi">Throwable</span> e) 
<span class="pl-c"><span class="pl-c">//</span>结束</span>
<span class="pl-k">public</span> <span class="pl-k">void</span> end()</pre></div>
</li>
</ol>
<ul>
<li>
<p><strong>使用方式：</strong><br>
对自定义切面类继承AspectProxy抽象类，并重写目标方法， 然后对该类添加<a href="https://github.com/Aspect" class="user-mention">@Aspect</a>注解。</p>
<ul>
<li>
<p><strong>注解:<a href="https://github.com/Aspect" class="user-mention">@Aspect</a></strong> <em>（该注解有三个属性值：）</em>：<br>
<strong>pkg</strong>：想要被代理类所在的包名。<br>
<strong>cls</strong>：想要被代理的具体类，和pkg二选一。<br>
<strong>annotation</strong>：想要被代理的类是有指定注解的类</p>
</li>
<li>
<p><strong>注解:@AspectOrder</strong> ：<br>
该注解是<a href="https://github.com/Aspect" class="user-mention">@Aspect</a>的补充，对链式AOP做排序，若有@AspectOrder注解，则优先比较（序号的值越小越靠前）</p>
</li>
<li>
<p><strong>代码示例：</strong></p>
<div class="highlight highlight-source-java"><pre> <span class="pl-k">package</span> <span class="pl-smi">com.demo.mvc.aop</span>;
 <span class="pl-k">import</span> <span class="pl-smi">java.lang.reflect.Method</span>;
 
 <span class="pl-k">import</span> <span class="pl-smi">org.slf4j.Logger</span>;
 <span class="pl-k">import</span> <span class="pl-smi">org.slf4j.LoggerFactory</span>;
 <span class="pl-k">import</span> <span class="pl-smi">com.jplus.core.aop.AspectProxy</span>;
 <span class="pl-k">import</span> <span class="pl-smi">com.jplus.core.aop.annotation.Aspect</span>;
 <span class="pl-k">import</span> <span class="pl-smi">com.jplus.core.mvc.DataContext</span>;
 <span class="pl-k">import</span> <span class="pl-smi">com.jplus.core.mvc.annotation.Controller</span>;
 
 <span class="pl-c"><span class="pl-c">/*</span>*</span>
<span class="pl-c"> * AOP拦截器演示&lt;br/&gt;</span>
<span class="pl-c"> * 测试拦截指定包名下所有的Action</span>
<span class="pl-c"> * @author Yuanqy</span>
<span class="pl-c"> <span class="pl-c">*/</span></span>
 <span class="pl-k">@Aspect</span>(<span class="pl-c1">pkg</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>com.demo.mvc.action<span class="pl-pds">"</span></span>, <span class="pl-c1">annotation</span> <span class="pl-k">=</span> <span class="pl-smi">Controller</span><span class="pl-k">.</span>class)
 <span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-en">ActionInterceptor</span> <span class="pl-k">extends</span> <span class="pl-e">AspectProxy</span> {
   <span class="pl-k">private</span> <span class="pl-smi">Logger</span> logger <span class="pl-k">=</span> <span class="pl-smi">LoggerFactory</span><span class="pl-k">.</span>getLogger(getClass());
 
   <span class="pl-k">ThreadLocal&lt;<span class="pl-smi">Long</span>&gt;</span> curTimes <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-k">ThreadLocal&lt;<span class="pl-smi">Long</span>&gt;</span>();
 
   <span class="pl-k">@Override</span>
   <span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">before</span>(<span class="pl-k">Class&lt;?&gt;</span> <span class="pl-v">cls</span>, <span class="pl-smi">Method</span> <span class="pl-v">method</span>, <span class="pl-k">Object</span>[] <span class="pl-v">params</span>) <span class="pl-k">throws</span> <span class="pl-smi">Throwable</span> {
     curTimes<span class="pl-k">.</span>set(<span class="pl-smi">System</span><span class="pl-k">.</span>currentTimeMillis());
     logger<span class="pl-k">.</span>info(<span class="pl-s"><span class="pl-pds">"</span>===Is new RequestURI：<span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-smi">DataContext</span><span class="pl-k">.</span>getRequest()<span class="pl-k">.</span>getRequestURI());
     logger<span class="pl-k">.</span>info(<span class="pl-s"><span class="pl-pds">"</span>===Action:{}.{}<span class="pl-pds">"</span></span>, cls<span class="pl-k">.</span>getName(), method<span class="pl-k">.</span>getName());
   }
 
   <span class="pl-k">@Override</span>
   <span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">after</span>(<span class="pl-k">Class&lt;?&gt;</span> <span class="pl-v">cls</span>, <span class="pl-smi">Method</span> <span class="pl-v">method</span>, <span class="pl-k">Object</span>[] <span class="pl-v">params</span>, <span class="pl-smi">Object</span> <span class="pl-v">result</span>) <span class="pl-k">throws</span> <span class="pl-smi">Throwable</span> {
     logger<span class="pl-k">.</span>info(<span class="pl-s"><span class="pl-pds">"</span>===Action is complete,time：{}ms <span class="pl-cce">\n</span><span class="pl-pds">"</span></span>, (<span class="pl-smi">System</span><span class="pl-k">.</span>currentTimeMillis() <span class="pl-k">-</span> curTimes<span class="pl-k">.</span>get()));
     curTimes<span class="pl-k">.</span>remove();
   }
 }</pre></div>
</li>
</ul>
</li>
</ul>
<ol>
<li>
<p><strong>TransactionProxy.java</strong> 事务代理：</p>
<ul>
<li>
<p><strong>使用方式：</strong><br>
在想要被事务代理的类、或类的方法上添加注解：<strong><a href="https://github.com/Transaction" class="user-mention">@Transaction</a></strong>即可。</p>
</li>
<li>
<p><strong>注解:<a href="https://github.com/Transaction" class="user-mention">@Transaction</a></strong>：<br>
类似于Spring的事务，支持事务传播，支持配置事务隔离级别（默认level=4）<br>
作用于类上，表示当前类中所有方法开启事务。<br>
作用于方法上，表示当前方法开启事务。</p>
</li>
<li>
<p><strong>代码示例：</strong></p>
<div class="highlight highlight-source-java"><pre><span class="pl-k">@Service</span>
<span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-en">UserService</span> {

	<span class="pl-k">@Transaction</span>
	<span class="pl-k">public</span> <span class="pl-smi">Result</span> <span class="pl-en">add</span>(<span class="pl-smi">User</span> <span class="pl-v">form</span>) {
		<span class="pl-smi">Result</span> res <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">Result</span>()<span class="pl-c1"><span class="pl-k">.</span>OK</span>();
		<span class="pl-c"><span class="pl-c">//</span> TODO something...</span>
		<span class="pl-k">return</span> res;
	}
}</pre></div>
</li>
</ul>
</li>
<li>
<p><strong>PluginProxy.java</strong> 插件代理：</p>
<ul>
<li><strong>使用方式：</strong><br>
他是对于上诉两种代理的补充，可以用于扩展任意规则、任意场景代理实现。<br>
该类仅有一个获取代理链方法：
<div class="highlight highlight-source-java"><pre>  <span class="pl-c"><span class="pl-c">/*</span>*</span>
<span class="pl-c">  * 具体代理被执行时，会执行实现了Proxy接口的doProxy()方法. </span>
<span class="pl-c">  * 使用方式：请参考：com.jplus.j2cache.proxy.J2CachePluginProxy</span>
<span class="pl-c">  * 原理：</span>
<span class="pl-c">  * 项目启动时，先扫描缓存bean，当AopHandle运行时，执行插件代理的getTargetClassList方法。</span>
<span class="pl-c">  * 该方法由开发人员自己定义筛选规则，将满足条件的对象bean集合返回，做AOP代理；</span>
<span class="pl-c">  * 在项目运行期，代理的对象执行时，通过链式代理，找到当前类，执行doProxy()方法，完成代理操作。</span>
<span class="pl-c">  <span class="pl-c">*/</span></span>
  <span class="pl-k">public</span> <span class="pl-k">abstract</span> <span class="pl-k">List&lt;<span class="pl-k">Class&lt;?&gt;</span>getTargetClassList(</span>)</pre></div>
</li>
</ul>
</li>
</ol>
<h3>4. 关于JplusIOC的相关配置</h3>
<blockquote>
<p>框架中，ioc初始化位于项目启动最后阶段。 之前的MVC，AOP，Plugin 已经是创建了所有项目中所需的bean对象， 在最后要做的就是把这些 对象 互相关联起来，建立原本的依赖关系。</p>
</blockquote>
<ul>
<li>
<p><strong>注解:<a href="https://github.com/Autowired" class="user-mention">@Autowired</a></strong>：</p>
<ul>
<li>
<p><strong>使用方式：</strong></p>
<div class="highlight highlight-source-java"><pre><span class="pl-c"><span class="pl-c">//</span>通过接口注入，框架会找到容器中的第一个接口实现类进行注入，实现类必须&gt;=1，否则异常</span>
<span class="pl-k">private</span> <span class="pl-k">@Autowired</span> <span class="pl-smi">IIocDemo</span> demo;<span class="pl-c"><span class="pl-c">//</span> 通过接口注入</span>

<span class="pl-c"><span class="pl-c">//</span>通过指定接口实现注入，实现类上必须标明当前名称@Service("xxx")才能注入成功</span>
<span class="pl-k">private</span> <span class="pl-k">@Autowired</span>(<span class="pl-s"><span class="pl-pds">"</span>xxx<span class="pl-pds">"</span></span>) <span class="pl-smi">IIocDemo</span> demo;<span class="pl-c"><span class="pl-c">//</span> 通过指定接口实现注入</span>

<span class="pl-c"><span class="pl-c">//</span>这个没什么好说的，直接注入目标类即可</span>
<span class="pl-c"><span class="pl-c">//</span>PS.只要是bean容器管理了的对象，都可通过@Autowired注入。</span>
<span class="pl-k">private</span> <span class="pl-k">@Autowired</span> <span class="pl-smi">IocDemoImpl</span> demo;<span class="pl-c"><span class="pl-c">//</span> 通过指定对象注入</span></pre></div>
</li>
</ul>
</li>
<li>
<p><strong>注解:<a href="https://github.com/Value" class="user-mention">@Value</a></strong>：</p>
<ul>
<li>
<p><strong>使用方式：</strong></p>
<div class="highlight highlight-source-java"><pre><span class="pl-c"><span class="pl-c">//</span>方式1：@Value("xxx")</span>
<span class="pl-c"><span class="pl-c">//</span>方式2：@Value("${xxx}") 两种方式效果一致</span>
<span class="pl-k">private</span> <span class="pl-k">@Value</span>(<span class="pl-s"><span class="pl-pds">"</span>app.scan.pkg<span class="pl-pds">"</span></span>) <span class="pl-smi">String</span> scanPkg;<span class="pl-c"><span class="pl-c">//</span> 注入配置文件</span></pre></div>
</li>
</ul>
</li>
<li>
<p><strong>注解:<a href="https://github.com/Component" class="user-mention">@Component</a></strong>：<br>
<a href="https://github.com/Component" class="user-mention">@Component</a>注解是其他注解的元注解。jplus的扫描规则是扫描所有继承或使用Component注解的类，然后加入bean管理。</p>
<ul>
<li><strong>使用方式：</strong>
<div class="highlight highlight-source-java"><pre><span class="pl-c"><span class="pl-c">/*</span>*</span>
<span class="pl-c">* 属于Bean扫描注解，任何需要加入IOC的组件类，都 可以添加该注解。</span>
<span class="pl-c">* 该注解提供两个参数[都非必填项]：</span>
<span class="pl-c">* initMethod：填入当前类的方法名，项目启动后会执行该方法</span>
<span class="pl-c">* destroyMethod：填入当前类的方法名，项目注销前会执行该方法</span>
<span class="pl-c"><span class="pl-c">*/</span></span>
<span class="pl-k">@Component</span>(<span class="pl-c1">initMethod</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>init<span class="pl-pds">"</span></span>, <span class="pl-c1">destroyMethod</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>destroy<span class="pl-pds">"</span></span>)
<span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-en">InitComponent</span> {
  <span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">init</span>() {
    <span class="pl-smi">System</span><span class="pl-k">.</span>err<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>== 项目启动后会执行该方法 ==<span class="pl-pds">"</span></span>);
  }

  <span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">destroy</span>() {
    <span class="pl-smi">System</span><span class="pl-k">.</span>err<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>== 项目注销前会执行该方法 ==<span class="pl-pds">"</span></span>);
  }
}</pre></div>
</li>
</ul>
</li>
<li>
<p><strong>代码示例：</strong></p>
<div class="highlight highlight-source-java"><pre>  <span class="pl-c"><span class="pl-c">/*</span>*</span>
<span class="pl-c">  * 接口类</span>
<span class="pl-c">  <span class="pl-c">*/</span></span>
  <span class="pl-k">public</span> <span class="pl-k">interface</span> <span class="pl-en">IIocDemo</span> {
  <span class="pl-smi">Result</span> <span class="pl-en">addUser</span>(<span class="pl-smi">User</span> <span class="pl-v">user</span>);
  <span class="pl-smi">Result</span> <span class="pl-en">getUser</span>(<span class="pl-k">int</span> <span class="pl-v">id</span>);
  }</pre></div>
<hr>
<div class="highlight highlight-source-java"><pre>  <span class="pl-c"><span class="pl-c">/*</span>*</span>
<span class="pl-c">  * 实现类</span>
<span class="pl-c">  <span class="pl-c">*/</span></span>
  <span class="pl-c"><span class="pl-c">//</span>@Service</span>
  <span class="pl-k">@Service</span>(<span class="pl-s"><span class="pl-pds">"</span>iocDemoImpl<span class="pl-pds">"</span></span>)
  <span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-en">IocDemoImpl</span> <span class="pl-k">implements</span> <span class="pl-e">IIocDemo</span> {

    <span class="pl-k">private</span> <span class="pl-k">Map&lt;<span class="pl-smi">Integer</span>, <span class="pl-smi">User</span>&gt;</span> map <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-k">HashMap&lt;&gt;</span>();

    <span class="pl-k">@Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">Result</span> <span class="pl-en">addUser</span>(<span class="pl-smi">User</span> <span class="pl-v">user</span>) {
      map<span class="pl-k">.</span>put(user<span class="pl-k">.</span>getId(), user);
      <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-smi">Result</span>()<span class="pl-c1"><span class="pl-k">.</span>OK</span>()<span class="pl-c1"><span class="pl-k">.</span>DATA</span>(<span class="pl-s"><span class="pl-pds">"</span>新增成功<span class="pl-pds">"</span></span>);
    }

    <span class="pl-k">@Override</span>
    <span class="pl-k">public</span> <span class="pl-smi">Result</span> <span class="pl-en">getUser</span>(<span class="pl-k">int</span> <span class="pl-v">id</span>) {
      <span class="pl-k">if</span> (map<span class="pl-k">.</span>containsKey(id))
      <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-smi">Result</span>()<span class="pl-c1"><span class="pl-k">.</span>OK</span>()<span class="pl-c1"><span class="pl-k">.</span>DATA</span>(map<span class="pl-k">.</span>get(id));
      <span class="pl-k">else</span>
      <span class="pl-k">return</span> <span class="pl-k">new</span> <span class="pl-smi">Result</span>()<span class="pl-c1"><span class="pl-k">.</span>FAIL</span>()<span class="pl-c1"><span class="pl-k">.</span>DATA</span>(<span class="pl-s"><span class="pl-pds">"</span>数据不存在<span class="pl-pds">"</span></span>);
    }
  }</pre></div>
<hr>
<div class="highlight highlight-source-java"><pre>  <span class="pl-c"><span class="pl-c">/*</span>*</span>
<span class="pl-c">  * 在Action中注入</span>
<span class="pl-c">  <span class="pl-c">*/</span></span>
  <span class="pl-k">@Controller</span>
  <span class="pl-k">@Request</span>(<span class="pl-s"><span class="pl-pds">"</span>ioc/<span class="pl-pds">"</span></span>)
  <span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-en">IocAction</span> {

    <span class="pl-k">private</span> <span class="pl-k">@Autowired</span> <span class="pl-smi">IIocDemo</span> ioc1;			<span class="pl-c"><span class="pl-c">//</span> 通过接口注入</span>
    <span class="pl-k">private</span> @<span class="pl-en">Autowired</span>("<span class="pl-v">iocDemoImpl</span>") IIocDemo ioc2;	<span class="pl-c"><span class="pl-c">//</span> 通过指定接口实现注入</span>
    <span class="pl-k">private</span> <span class="pl-k">@Autowired</span> <span class="pl-smi">IocDemoImpl</span> ioc3;		<span class="pl-c"><span class="pl-c">//</span> 通过指定对象注入</span>

    <span class="pl-k">private</span> @<span class="pl-en">Value</span>("<span class="pl-v">app</span>.<span class="pl-v">scan</span>.<span class="pl-v">pkg</span>") String scanPkg;

    <span class="pl-k">@Request.Get</span>(<span class="pl-s"><span class="pl-pds">"</span>test<span class="pl-pds">"</span></span>)
    <span class="pl-k">private</span> <span class="pl-k">void</span> <span class="pl-en">iocTest</span>() {
      <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(ioc1<span class="pl-k">.</span>addUser(<span class="pl-k">new</span> <span class="pl-smi">User</span>(<span class="pl-c1">1</span>, <span class="pl-s"><span class="pl-pds">"</span>张三<span class="pl-pds">"</span></span>)));
      <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(ioc2<span class="pl-k">.</span>getUser(<span class="pl-c1">1</span>));
      <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(ioc3<span class="pl-k">.</span>getUser(<span class="pl-c1">1</span>));

      <span class="pl-smi">WebUtil</span><span class="pl-k">.</span>writeTEXT(<span class="pl-s"><span class="pl-pds">"</span>OK<span class="pl-pds">"</span></span>);
    }
  }</pre></div>
</li>
</ul>
<h3>5. 关于Jplus Junit的相关配置</h3>
<blockquote>
<p>jplus框架默认集成 <strong>Junit4</strong> 单元测试框架。</p>
</blockquote>
<ul>
<li>
<p><strong>使用方式：</strong></p>
<p>测试类添加两个注解：@RunWith [Junit框架注解]、@ContextConfiguration [Jplus框架注解] 即可。<br>
RunWith注解大家可以百度下使用方式，现在说明下ContextConfiguration注解。</p>
<ul>
<li>
<p><strong>注解：@ContextConfiguration</strong><br>
ContextConfiguration用于配置配置文件路径。通过参数locations配置，说明如下：</p>
<pre><code>"file:/app.properties"			//系统根目录 
"app.properties"			//项目根目录 
"/app.properties"			//项目WEB-INF下 
"classpath:app.properties"		//项目ClassPath下

//如果有多个配置文件，可以用 ; 分号分割，如下：
"file:/db.properties;classpath:app.properties"	//多个配置文件.一个文件目录下;一个classpath目录
</code></pre>
</li>
<li>
<p><strong>代码示例：</strong></p>
<div class="highlight highlight-source-java"><pre><span class="pl-c"><span class="pl-c">/*</span>*</span>
<span class="pl-c">* JplusJunit4 测试框架IOC功能</span>
<span class="pl-c"><span class="pl-c">*/</span></span>
<span class="pl-k">@RunWith</span>(<span class="pl-smi">JplusJunit4Runner</span><span class="pl-k">.</span>class)
<span class="pl-k">@ContextConfiguration</span>(<span class="pl-c1">locations</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>classpath:app.properties<span class="pl-pds">"</span></span>)
<span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-en">JunitIOC</span> {

  <span class="pl-k">private</span> @<span class="pl-en">Autowired</span>("<span class="pl-v">iocDemoImpl</span>") IIocDemo ioc3;
  <span class="pl-k">private</span> <span class="pl-k">@Autowired</span> <span class="pl-smi">IocDemoImpl</span> ioc2;

  <span class="pl-k">private</span> @<span class="pl-en">Value</span>("<span class="pl-v">app</span>.<span class="pl-v">scan</span>.<span class="pl-v">pkg</span>") String scanPkg;

  <span class="pl-k">@Test</span>
  <span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">test</span>() <span class="pl-k">throws</span> <span class="pl-smi">InterruptedException</span> {
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>添加用户：<span class="pl-pds">"</span></span> <span class="pl-k">+</span> ioc3<span class="pl-k">.</span>addUser(<span class="pl-k">new</span> <span class="pl-smi">User</span>(<span class="pl-c1">1001</span>, <span class="pl-s"><span class="pl-pds">"</span>Jplus<span class="pl-pds">"</span></span>)));
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>获取用户：<span class="pl-pds">"</span></span> <span class="pl-k">+</span> ioc2<span class="pl-k">.</span>getUser(<span class="pl-c1">1001</span>));
    <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>app.scan.pkg=<span class="pl-pds">"</span></span> <span class="pl-k">+</span> scanPkg);

    <span class="pl-smi">Thread</span><span class="pl-k">.</span>currentThread()<span class="pl-k">.</span>join();
  }
}</pre></div>
</li>
</ul>
</li>
</ul>
<h3>6. 关于JplusMVC的后端参数验证</h3>
<blockquote>
<p>对于请求入参，JPlus可以通过拦截器做公共参数校验，对于form表单对象，可以使用工具类进行校验。</p>
</blockquote>
<ul>
<li>
<p><strong>使用方式：</strong><br>
对于form表单对象（可以理解为添加了<a href="https://github.com/Form" class="user-mention">@Form</a>注解的pojo类），当该对象作为请求入参时，正常情况参数的校验都是固定的字段，固定的规则。而且开发人员也不想在业务代码里面进行入参判断。这时候就可以使用：**Result res= VerifyUtil.doVerify(form)；**通过返回Result判断校验结果。<br>
原理:对入参对象的字段进行处理，判断是否有<a href="https://github.com/V" class="user-mention">@V</a>注解，对<a href="https://github.com/V" class="user-mention">@V</a>注解的字段进行判断处理。</p>
</li>
<li>
<p><strong>注解 <a href="https://github.com/V" class="user-mention">@V</a>：</strong></p>
<table>
<thead>
<tr>
<th align="left">注解名</th>
<th align="left">默认表达式</th>
<th align="left">默认返回描述</th>
<th align="center">是否可为空</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">IsNotNull</td>
<td align="left">\w+</td>
<td align="left">字段{}不能为空</td>
<td align="center">FALSE</td>
</tr>
<tr>
<td align="left">IsCN</td>
<td align="left">^[\u4e00-\u9fa5]+$</td>
<td align="left">字段{}不是汉字</td>
<td align="center">TRUE</td>
</tr>
<tr>
<td align="left">IsDigits</td>
<td align="left">^[0-9]*$</td>
<td align="left">字段{}不是纯数字</td>
<td align="center">TRUE</td>
</tr>
<tr>
<td align="left">IsFloat</td>
<td align="left">^[0-9]*$</td>
<td align="left">字段{}不是小数</td>
<td align="center">TRUE</td>
</tr>
<tr>
<td align="left">IsEmail</td>
<td align="left">^\w+([-+.]\w+)<em>@\w+([-.]\w+)</em>\.\w+([-.]\w+)*$</td>
<td align="left">邮箱格式不正确</td>
<td align="center">TRUE</td>
</tr>
<tr>
<td align="left">IsIdCardNo</td>
<td align="left">^(\d{6})()?(\d{4})(\d{2})(\d{2})(\d{3})(\w)$</td>
<td align="left">身份证号不正确</td>
<td align="center">TRUE</td>
</tr>
<tr>
<td align="left">IsPhone</td>
<td align="left">^[1][0-9]{10}$</td>
<td align="left">手机号码不正确</td>
<td align="center">TRUE</td>
</tr>
<tr>
<td align="left">IsPwd</td>
<td align="left">^(?![0-9]+$)(?![a-zA-Z]+$)[0-9A-Za-z]{6,16}$</td>
<td align="left">密码格式不正确</td>
<td align="center">TRUE</td>
</tr>
<tr>
<td align="left">IsTel</td>
<td align="left">^(0\d{2}-\d{8}(-\d{1,4})?)|(0\d{3}-\d{7,8}(-\d{1,4})?)$</td>
<td align="left">电话号码不正确</td>
<td align="center">TRUE</td>
</tr>
<tr>
<td align="left">IsZipCode</td>
<td align="left">^[0-9]{6}$</td>
<td align="left">邮政编码不正确</td>
<td align="center">TRUE</td>
</tr>
<tr>
<td align="left">Custom</td>
<td align="left"></td>
<td align="left">未定义</td>
<td align="center">TRUE</td>
</tr></tbody></table>
<p><em>PS：@V.Custom()用于给用户自定义校验规则及返回说明。还支持JPEL表达式。</em></p>
</li>
<li>
<p><strong>代码示例：</strong></p>
<div class="highlight highlight-source-java"><pre> <span class="pl-c"><span class="pl-c">/*</span>*</span>
<span class="pl-c"> * Form入参表单</span>
<span class="pl-c"> <span class="pl-c">*/</span></span>
 <span class="pl-k">@Form</span> 
 <span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-en">User</span> {
 	<span class="pl-k">@V</span><span class="pl-k">.</span><span class="pl-smi">IsNotNull</span>
 	<span class="pl-k">@V</span><span class="pl-k">.</span><span class="pl-smi">IsDigits</span>
 	<span class="pl-k">private</span> <span class="pl-k">int</span> id;			<span class="pl-c"><span class="pl-c">//</span>表示id必须为数字，不能为空</span>
 	<span class="pl-k">private</span> <span class="pl-smi">String</span> name;
 
 	<span class="pl-k">@V.Custom</span>(<span class="pl-c1">regex</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>el:{}&gt;=18 &amp;&amp; {}&lt;30<span class="pl-pds">"</span></span>, <span class="pl-c1">retmsg</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>年龄必须在18~30岁之间<span class="pl-pds">"</span></span>,<span class="pl-c1">isNull</span><span class="pl-k">=</span><span class="pl-c1">false</span>)
 	<span class="pl-k">private</span> <span class="pl-smi">String</span> age;		<span class="pl-c"><span class="pl-c">//</span>表示 自定义用JPEL表达式判断年龄范围，不能为空</span>
 	<span class="pl-k">@V.Custom</span>(<span class="pl-c1">regex</span><span class="pl-k">=</span><span class="pl-s"><span class="pl-pds">"</span>^[A-Za-z]+$<span class="pl-pds">"</span></span>,<span class="pl-c1">retmsg</span><span class="pl-k">=</span><span class="pl-s"><span class="pl-pds">"</span>请输入正确的URL<span class="pl-pds">"</span></span>)
 	<span class="pl-k">private</span> <span class="pl-smi">String</span> url;		<span class="pl-c"><span class="pl-c">//</span>表示 自定义用正则表达式判断</span>
 	<span class="pl-k">@V</span><span class="pl-k">.</span><span class="pl-smi">IsPhone</span>
 	<span class="pl-k">private</span> <span class="pl-smi">String</span> phone;	<span class="pl-c"><span class="pl-c">//</span>表示 必须为手机号，可为空</span>
 }
 <span class="pl-c"><span class="pl-c">//</span>======================================================</span>
 <span class="pl-k">@Controller</span>
 <span class="pl-k">@Request</span>(<span class="pl-s"><span class="pl-pds">"</span>user/<span class="pl-pds">"</span></span>)
 <span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-en">UserAction</span> {
 	<span class="pl-k">private</span> <span class="pl-k">@Autowired</span> <span class="pl-smi">UserService</span> userService;
 	
 	<span class="pl-k">@Request.Post</span>(<span class="pl-s"><span class="pl-pds">"</span>add<span class="pl-pds">"</span></span>)
 	<span class="pl-k">private</span> <span class="pl-smi">Result</span> <span class="pl-en">addUser</span>(<span class="pl-smi">User</span> <span class="pl-v">form</span>) {
 		<span class="pl-c"><span class="pl-c">//</span>执行入参验证</span>
 		<span class="pl-smi">Result</span> res <span class="pl-k">=</span> <span class="pl-smi">VerifyUtil</span><span class="pl-k">.</span>doVerify(form);
 		<span class="pl-k">if</span> (<span class="pl-smi">res<span class="pl-k">.</span>IsOK</span>())
 			<span class="pl-k">return</span> userService<span class="pl-k">.</span>add(form);
 		<span class="pl-k">return</span> res;
 	}
 }</pre></div>
</li>
</ul>
<h3>7. 附加：关于Jplus的JPEL表达式的使用</h3>
<ul>
<li>
<p><strong>使用逆波兰算法实现，相比js引擎，效率提升&gt;15倍,后续会逐渐优化,支持特性：</strong></p>
<ul>
<li>算数运算表达式:<br>
加(+)、减(-)、乘(*)、除(/)、求余（%）、幂（^）运算</li>
<li>关系表达式:<br>
等于（==）、不等于(!=)、大于(&gt;)、大于等于(&gt;=)、小于(&lt;)、小于等于(&lt;=)</li>
<li>逻辑表达式:<br>
且（&amp;&amp;）、或( || )、非( ! )、true、false</li>
<li>括号优先级表达式:<br>
使用“(表达式)”构造，括号里的具有高优先级。</li>
<li>不支持三目运算，不支持文本字符串</li>
</ul>
</li>
<li>
<p><strong>使用方式：</strong></p>
<div class="highlight highlight-source-java"><pre> <span class="pl-c"><span class="pl-c">//</span>参见代码：com.jplus.core.util.JPEL.java</span>

 <span class="pl-smi">String</span> calc <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>1+2*(3+4)-5+(-2)*8/2+8 == 5*6/2-5 &amp;&amp; 10%4*3&gt;-1+2*3<span class="pl-pds">"</span></span>;
 <span class="pl-smi">System</span><span class="pl-k">.</span>err<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>中缀表达式：<span class="pl-pds">"</span></span> <span class="pl-k">+</span> calc);
 <span class="pl-c"><span class="pl-c">//</span> == 逆波兰 ========================</span>
 <span class="pl-k">long</span> t <span class="pl-k">=</span> <span class="pl-smi">System</span><span class="pl-k">.</span>currentTimeMillis();
 <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>逆波兰=<span class="pl-pds">"</span></span> <span class="pl-k">+</span> excute(calc) <span class="pl-k">+</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\t</span>time:<span class="pl-pds">"</span></span> <span class="pl-k">+</span> (<span class="pl-smi">System</span><span class="pl-k">.</span>currentTimeMillis() <span class="pl-k">-</span> t));
 <span class="pl-c"><span class="pl-c">//</span> == JS引擎==========================</span>
 t <span class="pl-k">=</span> <span class="pl-smi">System</span><span class="pl-k">.</span>currentTimeMillis();
 <span class="pl-smi">System</span><span class="pl-k">.</span>out<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>JS引擎=<span class="pl-pds">"</span></span> <span class="pl-k">+</span> getSE()<span class="pl-k">.</span>eval(calc) <span class="pl-k">+</span> <span class="pl-s"><span class="pl-pds">"</span><span class="pl-cce">\t</span>time:<span class="pl-pds">"</span></span> <span class="pl-k">+</span> (<span class="pl-smi">System</span><span class="pl-k">.</span>currentTimeMillis() <span class="pl-k">-</span> t));</pre></div>
</li>
</ul>
<h3>8. 附加：关于Jplus多数据源的配置</h3>
<blockquote>
<p>多数据源可以支持<strong>申明式配置</strong>和<strong>编程式配置</strong>两种，具体方法参考jplus-orm说明文档。</p>
</blockquote>
<ul>
<li><strong>编程式配置 实例：</strong>
<div class="highlight highlight-source-java"><pre> <span class="pl-c"><span class="pl-c">/*</span>*</span>
<span class="pl-c">  * JplusJunit4 测试Jplus-core编程式多数据源切换</span>
<span class="pl-c">  <span class="pl-c">*/</span></span>
 <span class="pl-k">@RunWith</span>(<span class="pl-smi">JplusJunit4Runner</span><span class="pl-k">.</span>class)
 <span class="pl-k">@ContextConfiguration</span>(<span class="pl-c1">locations</span> <span class="pl-k">=</span> <span class="pl-s"><span class="pl-pds">"</span>classpath:app.properties<span class="pl-pds">"</span></span>)
 <span class="pl-k">public</span> <span class="pl-k">class</span> <span class="pl-en">JplusDDS</span> {
 
 	<span class="pl-k">@Test</span>
 	<span class="pl-k">public</span> <span class="pl-k">void</span> <span class="pl-en">test</span>() {
 		<span class="pl-smi">JdbcTemplate</span> jt <span class="pl-k">=</span> <span class="pl-c1">null</span>;
 		<span class="pl-k">try</span> {
 			<span class="pl-c"><span class="pl-c">//</span> 1.创建N个数据源，可选用C3p0，Druid...都可以</span>
 			<span class="pl-smi">DataSource</span> ds1 <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">C3p0Plugin</span>(<span class="pl-s"><span class="pl-pds">"</span>jdbc:mysql://139.196.18.60:3306<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>root<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>password<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>com.mysql.jdbc.Driver<span class="pl-pds">"</span></span>)<span class="pl-k">.</span>getDataSource();
 			<span class="pl-smi">DataSource</span> ds2 <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">C3p0Plugin</span>(<span class="pl-s"><span class="pl-pds">"</span>jdbc:mysql://192.168.1.16:3306<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>root<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>password<span class="pl-pds">"</span></span>, <span class="pl-s"><span class="pl-pds">"</span>com.mysql.jdbc.Driver<span class="pl-pds">"</span></span>)<span class="pl-k">.</span>getDataSource();
 			<span class="pl-c"><span class="pl-c">//</span> 2.将N个数据源放入DynamicDataSource中，并定义key名称</span>
 			<span class="pl-k">Map&lt;<span class="pl-smi">String</span>, <span class="pl-smi">DataSource</span>&gt;</span> map <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-k">HashMap&lt;<span class="pl-smi">String</span>, <span class="pl-smi">DataSource</span>&gt;</span>();
 			map<span class="pl-k">.</span>put(<span class="pl-s"><span class="pl-pds">"</span>readone<span class="pl-pds">"</span></span>, ds1);
 			map<span class="pl-k">.</span>put(<span class="pl-s"><span class="pl-pds">"</span>readtwo<span class="pl-pds">"</span></span>, ds2);
 			<span class="pl-smi">DynamicDataSource</span> dds <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">DynamicDataSource</span>(map);
 			<span class="pl-c"><span class="pl-c">//</span> 3.创建一个JdbcTemplate，使用数据源为DynamicDataSource</span>
 			jt <span class="pl-k">=</span> <span class="pl-k">new</span> <span class="pl-smi">JdbcTemplate</span>(dds);
 
 			<span class="pl-c"><span class="pl-c">//</span> 4.循环测试数据源切换[ps.我事先准备了两个不同版本的mysql]</span>
 			<span class="pl-k">for</span> (<span class="pl-k">int</span> i <span class="pl-k">=</span> <span class="pl-c1">0</span>; i <span class="pl-k">&lt;</span> <span class="pl-c1">3</span>; i<span class="pl-k">++</span>) {
 				<span class="pl-k">if</span> (i <span class="pl-k">==</span> <span class="pl-c1">2</span>)
 					jt<span class="pl-k">.</span>openTransaction(); <span class="pl-c"><span class="pl-c">//</span> 最后一次开启事务</span>
 				<span class="pl-smi">DataSourceHolder</span><span class="pl-k">.</span>setDbType(<span class="pl-s"><span class="pl-pds">"</span>readone<span class="pl-pds">"</span></span>);
 				<span class="pl-smi">System</span><span class="pl-k">.</span>err<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>[切换1]:<span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-c1">JSON</span><span class="pl-k">.</span>toJSONString(jt<span class="pl-k">.</span>query(<span class="pl-s"><span class="pl-pds">"</span>SHOW VARIABLES LIKE 'version';<span class="pl-pds">"</span></span>, <span class="pl-k">new</span> <span class="pl-smi">Object</span>[] {})));
 				<span class="pl-smi">DataSourceHolder</span><span class="pl-k">.</span>setDbType(<span class="pl-s"><span class="pl-pds">"</span>readtwo<span class="pl-pds">"</span></span>);
 				<span class="pl-smi">System</span><span class="pl-k">.</span>err<span class="pl-k">.</span>println(<span class="pl-s"><span class="pl-pds">"</span>[切换2]:<span class="pl-pds">"</span></span> <span class="pl-k">+</span> <span class="pl-c1">JSON</span><span class="pl-k">.</span>toJSONString(jt<span class="pl-k">.</span>query(<span class="pl-s"><span class="pl-pds">"</span>SHOW VARIABLES LIKE 'version';<span class="pl-pds">"</span></span>, <span class="pl-k">new</span> <span class="pl-smi">Object</span>[] {})));
 				<span class="pl-k">if</span> (i <span class="pl-k">==</span> <span class="pl-c1">2</span>)
 					jt<span class="pl-k">.</span>commit(); <span class="pl-c"><span class="pl-c">//</span> 提交事务</span>
 			}
 		} <span class="pl-k">catch</span> (<span class="pl-smi">Exception</span> e) {
 			e<span class="pl-k">.</span>printStackTrace();
 			<span class="pl-k">if</span> (jt <span class="pl-k">!=</span> <span class="pl-c1">null</span>)
 				jt<span class="pl-k">.</span>rollback(); <span class="pl-c"><span class="pl-c">//</span> 回滚事务</span>
 		}
 
 	}
 }</pre></div>
</li>
</ul>
</body>
</html>
<!-- This document was created with MarkdownPad, the Markdown editor for Windows (http://markdownpad.com) -->
